#include "stdafx.h"
#include "clist.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#pragma warning(disable : 4996)

// internal helper functions
char clist_is_full(clist *clisto)
{
	return(clisto->item_count == clisto->current_max_size);
}

void clist_grow(clist *old_clisto)
{
	int i;
	clist new_clisto;
	
	clist_make(&new_clisto, old_clisto->current_max_size*2, old_clisto->growable++);
	
	for(i=0; i<old_clisto->current_max_size; i++)
		clist_add_item(&new_clisto, old_clisto->items[i] , old_clisto->names[i]);
	
	clist_free(old_clisto);
	
	//copy new structure to old clist
	old_clisto->names = new_clisto.names;
	old_clisto->items = new_clisto.items;
	old_clisto->item_count = new_clisto.item_count;
	old_clisto->current_max_size = new_clisto.current_max_size;
	old_clisto->growable = new_clisto.growable;
}
//end helpers

void clist_make(clist *clisto, int start_size, char growable)
{
	clisto->names = (char**) malloc(sizeof(char*) * start_size);
	clisto->items = (void**) malloc(sizeof(void*) * start_size);
	clisto->item_count = 0;
	clisto->current_max_size = start_size;
	clisto->growable = growable;
}

int clist_add_item(clist *clisto, void *item, char *name)
{
	int name_length;
	char *new_name;
	
	if( clist_is_full(clisto) )
	{
		if( clisto->growable )
			clist_grow(clisto);
		else
			return -1;
	}
	
	clisto->names[clisto->item_count] = NULL;
	if(name != NULL)
	{
		name_length = strlen(name);
		new_name = (char*) malloc(sizeof(char) * name_length + 1);
		strncpy(new_name, name, name_length);
		clisto->names[clisto->item_count] = new_name;
	}

	clisto->items[clisto->item_count] = item;
	clisto->item_count++;
	
	return clisto->item_count-1;
}

char* clist_print_items(clist *clisto)
{
	int i;

	for(i=0; i < clisto->item_count; i++)
	{
		printf("%s\n", clisto->names[i]);
	}
	
	return NULL;
}

void* clist_get_index(clist *clisto, int indx)
{
	if(indx < clisto->item_count)
		return clisto->items[indx];
	return NULL;
}

void* clist_get_item(clist *clisto, void *item_to_find)
{
	int i = 0;
	
	for(i=0; i < clisto->item_count; i++)
	{
		if(clisto->items[i] == item_to_find)
			return clisto->items[i];
	}
	
	return NULL;
}

void* clist_get_name(clist *clisto, char *name_to_find)
{
	int i = 0;

	for(i=0; i < clisto->item_count; i++)
	{
		if(strncmp(clisto->names[i], name_to_find, strlen(name_to_find)) == 0)
			return clisto->items[i];
	}
	
	return NULL;
}

int clist_find(clist *clisto, char *name_to_find)
{
	int i = 0;

	for(i=0; i < clisto->item_count; i++)
	{
		if(strncmp(clisto->names[i], name_to_find, strlen(name_to_find)) == 0)
			return i;
	}
	
	return -1;
}

void clist_delete_item(clist *clisto, void *item)
{
	int i;
	
	for(i=0; i < clisto->item_count; i++)
	{		
		if( clisto->items[i] == item )
			clist_delete_index(clisto, i);
	}
}

void clist_delete_name(clist *clisto, char *name)
{
	int i;
	//int j;
	//char remove = 0;
	
	//	int length_name = strlen(name);
	int item_name;
	
	if(name == NULL)
		return;
	
	for(i=0; i < clisto->item_count; i++)
	{
		item_name = strlen(name);
				
		if( name != NULL && (strncmp(clisto->names[i], name, strlen(name)) == 0) )
			clist_delete_index(clisto, i);
	}
}

void clist_delete_index(clist *clisto, int indx)
{
	int j;
	
	//remove item
	if(clisto->names[indx] != NULL)
		free(clisto->names[indx]);
			
	//restructure
	for(j=indx; j < clisto->item_count-1; j++)
	{
		clisto->names[j] = clisto->names[j+1];
		clisto->items[j] = clisto->items[j+1];
	}
	
	clisto->item_count--;
	
	return;
}

void clist_delete_all(clist *clisto)
{
	int i;
	
	for(i=clisto->item_count-1; i>=0; i--)
		clist_delete_index(clisto, i);
}

void clist_free(clist *clisto)
{
	clist_delete_all(clisto);
	free(clisto->names);
	free(clisto->items);
}

void clist_print_clist(clist *clisto)
{
	int i;
	
	printf("count: %i/%i\n", clisto->item_count, clisto->current_max_size);
	
	for(i=0; i < clisto->item_count; i++)
	{
		printf("clist[%i]: %s\n", i, clisto->names[i]);
	}
}
